`include "fft_core_h.v"

module tb_fft_core();
  
  reg  [31:0] bus_wr;
  reg  [ 1:0] bus_addr;
  reg  read_en, write_en, clk, rst_n;
  
  wire [31:0] bus_rd;
  wire interrupt, busy_n, bus_rdy;
  
  reg [31:0] config_data;
  
  localparam MEM_SIZE = 8;
  reg [31:0] mem [0 : MEM_SIZE - 1];
  
  task reset;
    begin
      rst_n = 0;
      clk = 0;
      read_en = 0;
      write_en = 0;
      bus_addr = 2'b00;
      bus_wr = 32'd0;
      #50
      rst_n = 1;
    end
  endtask
  
  task bus_write;
    input [31:0] data;
    input [1:0] addr;
    begin
      @(negedge clk);
      write_en = 1;
      bus_addr = addr;
      bus_wr = data;
      wait(bus_rdy);
      @(negedge clk)
      write_en = 0;
    end
  endtask
  
  task bus_read;
    input [1:0] addr;
    output [31:0] data;
    begin
      @(negedge clk);
      read_en = 1;
      bus_addr = addr;
      @(posedge clk)
      wait(bus_rdy);
      data = bus_rd;
      @(posedge clk);
      read_en = 0;
    end
  endtask
  
  task config_core;
    input [31:0] config_data;
    begin
      bus_write(config_data, `CONFIG_REG);
    end
  endtask
  
  task read_config;
    output [31:0] config_data;
    begin
      bus_read(`CONFIG_REG, config_data);
    end
  endtask
  
  task init_mem;
    integer i;
    begin
      for(i = 0; i < 16; i = i + 1)
        begin
          bus_write(i, `MEM_WRITE);
        end
    end
  endtask
  
  task read_mem;
    integer i;
    begin
      for(i = 0; i < MEM_SIZE; i = i + 1)
        begin
          bus_read(`MEM_READ, mem[i]);
        end
    end
  endtask
  
  task display_mem;
    integer i;
    begin
      $display("Memory");
      $display("Addr\tData");
      for(i = 0; i < MEM_SIZE; i = i + 1)
        begin
          $display("%0d\t%0d",i, mem[i]);
        end
    end
  endtask
  
  
  fft_core FFT_CORE
  (
    .bus_rd    ( bus_rd    ),
    .bus_rdy   ( bus_rdy   ),
    .interrupt ( interrupt ),
    .busy_n    ( busy_n    ),
    .bus_wr    ( bus_wr    ),
    .bus_addr  ( bus_addr  ),
    .read_en   ( read_en   ),
    .write_en  ( write_en  ),
    .enable    (           ),
    .clk       ( clk       ),
    .rst_n     ( rst_n     )
  );
  
  initial
    begin
      reset;
      config_core(32'h00_00_00_10);
      init_mem;
      read_config(config_data);
      $display("Data Written:%x", 32'h00_00_00_10);
      $display("Data Read:%x", config_data);
      
      read_mem;
      display_mem;
      $stop;
    end
    
  always #10
    clk = !clk;
endmodule
